/**
 * Gallery
 * @param {Array} list data
 * @param {number} width window width
 * @param {number} column
 * @param {number} gap padding
 */
function Gallery (list, width, column, gap) {
  var L = JSON.parse(JSON.stringify(list)),
      aw = width/column,
      row = L.length/column >> 0,
      cacheRow = [],
      cacheRowWidth = 0,
      cacheR = 1,
      cacheNextWidth = 0,
      newList = [];

  // 统一图片高度
  var L = L.map(function (v) {
      v._width = aw*v.width/v.height;
      v._height = aw;
      return v
  });


  // 计算每行平均宽度
  var Rw = L.reduce(function(res, t, i, arr) {
      if (arr.length - arr.length%column < i) {
          return res
      }

      return (res._width || res) + t._width
  }) / row;


  // core
  L.forEach(function(v, i, arr) {
      cacheRow.push(v);
      cacheRowWidth+= v._width;
      cacheNextWidth = cacheRowWidth + (arr[i+1] ? arr[i+1]._width: 0);

      if (judgment()) {
          var r = cacheR = cacheRowWidth/width;

          if (gap) {
              r = cacheRowWidth/(width - gap*cacheRow.length);
          }

          newList = newList.concat(cacheRow.map(function (item) {
              item._width = item._width/r;
              item._height = item._height/r;

              if (gap) {
                item._width = floor(item._width + gap);
                item._height = floor(item._height + gap);
                item._padding = gap;
              }
              return item
          }));

          cacheRow = [];
          cacheRowWidth = 0;
      }

      if (i === (L.length - 1)) {
        var r = cacheR, endw = width;

        if (gap) {
            endw = width - gap*cacheRow.length
        }

        if (cacheRowWidth > endw) {
          r = cacheRowWidth/endw;
        }

        newList = newList.concat(cacheRow.map(function (item) {
          item._width = item._width/r;
          item._height = item._height/r;

          if (gap) {
            item._width = floor(item._width + gap);
            item._height = floor(item._height + gap);
            item._padding = gap;
          }
          return item
        }));
      }

  });

  // 换行规则
  function judgment() {
      if (cacheNextWidth >= (Rw + aw)) {
        return true
      }

      if (cacheRowWidth >= (Rw - (aw/2))) {
          return true
      }

      if (cacheRow.length >= column + 1) {
          return true
      }

      if (column === 1) {
          return true
      }

      return false
  }

  function floor (num) {
      return Math.floor(num * 100) / 100;
  }

  return newList;
}
